Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

64장. 실전 1 — 요구사항 하나로 기능 개발하기

지금까지 만든 것을 전부 써서
기능 하나를 처음부터 끝까지 한다.

과제는 20장에서 봤던 그 티켓이다.

[PAY-2841] 결제 실패 시 재시도 지원

고객사에서 PG 일시 오류로 결제가 실패하는 건이
하루 30건 정도 발생. 자동 재시도가 필요합니다.

세 줄이다.


준비 상태

CLAUDE.md            있음 (계층·컨벤션·금지사항)
settings.json        있음
Skills               add-api, migration-review, security-review, handoff
Subagents            explorer, planner, reviewer, db-reviewer
빠른 테스트           ./gradlew test --tests '*UnitTest'  (12초)
아키텍처 테스트        payment 도메인 포함
Jira · Grafana MCP   읽기 전용

61장의 HARNESS.md 에 정리된 상태다.


세션 1 — 티켓을 Task로 (25분)

PAY-2841 티켓과 댓글을 읽고 작업 Task로 변환해줘.

- 코드를 확인해서 영향받을 파일을 Scope에 넣어줘
- 내가 결정해야 하는 항목은 "결정 필요" 로 모아줘
- 구현은 하지 마

55장에서 말한 대로 댓글에 결정이 있었다.

댓글 (기획자, 3일 전):
"카드 한도 초과는 재시도하면 안 됩니다. 고객이 놀랍니다"

댓글 (PG 담당, 1일 전):
"멱등키는 이미 보내고 있는데 재시도 시 그대로 쓰면 됩니다"

두 번째가 중요하다.
30장에서 말한 재시도의 전제가 이미 있었다.

Agent가 뽑아온 결정 필요 는 넷이었다.

1. 재시도 이력을 별도 테이블로? → 아니오. payment 컬럼 추가
2. 3회 실패 후 처리? → 기존 슬랙 알림 채널 재사용
3. 재시도 중 사용자에게 노출? → 노출 안 함
4. 배치 정산이 같은 PgClient 사용 → 영향 확인 필요

🔥 4번은 Agent가 코드를 보고 찾아낸 것이다.

내가 몰랐던 항목이다.

사람이 결정한 것 ① — 네 항목의 답.


세션 2 — 조사와 계획 (40분)

explorer 로 PgClient 를 사용하는 모든 경로를 조사해줘.
결과는 docs/pg-client-usage.md 에 저장하고 요약만 보고해줘.

50장의 Context 격리를 쓴다.
파일 30여 개를 읽었지만 내 세션에는 요약만 들어왔다.

PgClient 사용처 4곳
  PaymentService.pay()           결제
  PaymentCancelHandler.cancel()  취소
  SettlementJob.reconcile()      정산 배치 ⚠️
  AdminPaymentService.forcePay() 관리자 강제 결제 ⚠️

⚠️ 뒤의 두 개가 문제였다.

정산 배치에 재시도가 붙으면
배치 시간이 3배로 늘어날 수 있다.

planner 로 계획을 세워줘. @docs/pg-client-usage.md 참고.
재시도는 결제 경로에만 적용하고 싶어.

계획서가 왔다. 21장의 다섯 요소 + 대안.

## 6. 대안
A. PgClient 에 @Retryable — 모든 호출자에 적용됨 ❌
B. 결제 전용 래퍼 클래스 추가 — 관심사 분리 ✅
C. 호출부에서 재시도 — 중복 코드

사람이 결정한 것 ② — B안 선택.

계획을 tasks/PAY-2841.md 에 저장하고 세션을 닫았다.


세션 3 — 분해 (10분)

22장의 방식으로 쪼갰다.

1. 재시도 대상 예외 분류 (PgTimeout / PgServerError)
2. 멱등키 재사용 검증 강화
3. retryCount 컬럼 마이그레이션
4. PaymentPgClient 래퍼 + 재시도 적용
5. 3회 실패 시 알림
6. 통합 테스트

의존 관계상 1·2·3은 독립,
4는 셋 다 필요, 5·6은 4 이후.

53장의 기준으로 병렬을 검토했지만
1·2가 같은 파일을 건드려서 순차로 갔다.


세션 4~6 — Task 1·2·3 구현 (각 30~50분)

각 세션이 커밋 하나로 끝났다.

Task 3에서 사고가 났다.

-- Agent가 만든 마이그레이션
ALTER TABLE payments ADD COLUMN retry_count INT NOT NULL DEFAULT 0;

migration-review Skill을 돌렸다.

/migration-review

## 스키마 변경
- NOT NULL 을 백필 전에 걸지 않았는가
  ⚠️ 문제있음. payments 테이블은 약 1,200만 행입니다.
  DEFAULT 가 있어 논리적으로는 통과하지만, MySQL 버전에 따라
  전체 테이블 rewrite 가 발생해 장시간 잠금 위험이 있습니다.

🔥 48장에서 만든 체크리스트가 실제로 잡았다.

27장에서 문장으로만 알던 규칙이
Skill 안에서 자동으로 적용됐다.

nullable 로 만들고, 백필은 별도 마이그레이션으로 분리해줘.

사람이 결정한 것 ③ — 3단계로 나눌지, DB 버전을 확인하고 갈지.
확인 결과 안전한 버전이었지만 나누는 쪽을 택했다.


세션 7 — Task 4 구현 (1시간)

핵심 작업이다.

지시에 30장의 항목을 넣었다.

@tasks/PAY-2841.md 의 Task 4 를 진행하자.

이번 범위:
- PaymentPgClient 래퍼 생성, 재시도 적용
- Task 1의 예외 분류 사용

이번 범위 아님:
- 알림 (Task 5)
- 정산 배치·관리자 경로 (재시도 적용 안 함)

완료 조건:
- 타임아웃 시 3회 재시도 테스트
- 잔액 부족은 재시도 안 함 테스트
- 같은 멱등키로 재시도해도 결제 1건 테스트
- 기존 결제 테스트 24건 통과

세 번째 완료 조건이 이 작업의 핵심이었다.

MockWebServer로 실패를 주입하는 테스트가 만들어졌고,
전부 통과했다.

⚠️ 여기서 놓친 것이 하나 있었다.

65장에서 드러난다.


세션 8 — 독립 Review (30분)

/clear 후 새 세션에서 시작했다.

52장의 원칙대로
구현 대화를 주지 않았다.

reviewer 와 db-reviewer 로 검토해줘.

대상: git diff main...HEAD
계획서: @tasks/PAY-2841.md

지적 네 개가 왔다.

#지적심각도판단
1재시도 중 커넥션 점유 시간 미검증높음반영
2알림 발송이 트랜잭션 안 (Task 5 예정)높음반영
3래퍼 클래스에 로깅 없음낮음부채로
4PgClient 를 deprecated 표시 권장낮음부채로

사람이 결정한 것 ④ — 1·2만 반영, 3·4는 tasks/tech-debt.md 로.

52장에서 말한 대로,
전부 반영하면 범위가 커진다.


PR과 배포 (다음 날)

이 브랜치의 커밋 6개를 읽고 PR 설명 초안을 만들어줘.
- 무엇을 왜 바꿨는지
- 리뷰어가 중점적으로 볼 부분
- 테스트한 내용

사람이 결정한 것 ⑤ — PR 생성, 리뷰어 지정.
사람이 결정한 것 ⑥ — 배포 승인.

59장의 세 관문이 다 작동했다.


정리

총 소요            약 6시간 (2일에 걸쳐)
커밋               6개, 각 40~120줄
세션               8개
사람이 결정한 지점   6곳
Agent가 찾아낸 것   내가 몰랐던 호출 경로 2곳, 마이그레이션 위험

⚠️ 6시간은 짧지 않다.

직접 했으면 하루 반쯤 걸렸을 작업이고,
아마 정산 배치 영향을 놓쳤을 것이다.

🔥 그리고 6시간 중 절반은 검토와 결정이었다.

1장에서 말한 시간 배분의 이동이
실제로 이렇게 나타난다.


이 장의 핵심

  • 티켓 본문이 아니라 댓글에 결정이 흩어져 있었다
  • Agent가 내가 몰랐던 호출 경로 두 곳을 찾아냈다
  • 조사를 Subagent에 위임해 메인 Context를 깨끗하게 유지했다
  • 계획서의 대안 항목이 더 나은 설계로 이어졌다
  • migration-review Skill이 1,200만 행 테이블의 위험을 잡았다
  • 문장으로만 알던 규칙이 Skill 안에서 자동 적용됐다
  • Review 지적 네 개 중 둘만 반영하고 둘은 부채로 넘겼다
  • 사람이 결정한 지점은 여섯 곳이었다
  • 총 6시간 중 절반이 검토와 결정이었다